Skip to content

[LLVM][Coverage][Unittest] Fix dangling reference in unittest #147118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

kikairoya
Copy link
Contributor

In loop of writeAndReadCoverageRegions, OutputFunctions[I].Filenames references to contents of Filenames after returning from readCoverageRegions but Filenames will be cleared in next call of readCoverageRegions, causes dangling reference.
The lifetime of the contents of Filenames must be equal or longer than OutputFunctions[I], thus it has been moved into OutputFunctions[I] (typed OutputFunctionCoverageData).

In loop of `writeAndReadCoverageRegions`, `OutputFunctions[I].Filenames` references to
contents of `Filenames` after returning from `readCoverageRegions` but `Filenames` will be
cleared in next call of `readCoverageRegions`, causes dangling reference.
The lifetime of the contents of `Filenames` must be equal or longer than `OutputFunctions[I]`,
thus it has been moved into `OutputFunctions[I]` (typed `OutputFunctionCoverageData`).
@llvmbot llvmbot added the PGO Profile Guided Optimizations label Jul 4, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 4, 2025

@llvm/pr-subscribers-pgo

Author: Tomohiro Kashiwada (kikairoya)

Changes

In loop of writeAndReadCoverageRegions, OutputFunctions[I].Filenames references to contents of Filenames after returning from readCoverageRegions but Filenames will be cleared in next call of readCoverageRegions, causes dangling reference.
The lifetime of the contents of Filenames must be equal or longer than OutputFunctions[I], thus it has been moved into OutputFunctions[I] (typed OutputFunctionCoverageData).


Full diff: https://github.com/llvm/llvm-project/pull/147118.diff

1 Files Affected:

  • (modified) llvm/unittests/ProfileData/CoverageMappingTest.cpp (+8-9)
diff --git a/llvm/unittests/ProfileData/CoverageMappingTest.cpp b/llvm/unittests/ProfileData/CoverageMappingTest.cpp
index ec81e5f274efa..59c381a1b4e82 100644
--- a/llvm/unittests/ProfileData/CoverageMappingTest.cpp
+++ b/llvm/unittests/ProfileData/CoverageMappingTest.cpp
@@ -64,6 +64,7 @@ namespace {
 struct OutputFunctionCoverageData {
   StringRef Name;
   uint64_t Hash;
+  std::vector<std::string> FilenamesStorage;
   std::vector<StringRef> Filenames;
   std::vector<CounterMappingRegion> Regions;
   std::vector<CounterExpression> Expressions;
@@ -71,8 +72,10 @@ struct OutputFunctionCoverageData {
   OutputFunctionCoverageData() : Hash(0) {}
 
   OutputFunctionCoverageData(OutputFunctionCoverageData &&OFCD)
-      : Name(OFCD.Name), Hash(OFCD.Hash), Filenames(std::move(OFCD.Filenames)),
-        Regions(std::move(OFCD.Regions)) {}
+      : Name(OFCD.Name), Hash(OFCD.Hash),
+        FilenamesStorage(std::move(OFCD.FilenamesStorage)),
+        Filenames(std::move(OFCD.Filenames)), Regions(std::move(OFCD.Regions)) {
+  }
 
   OutputFunctionCoverageData(const OutputFunctionCoverageData &) = delete;
   OutputFunctionCoverageData &
@@ -135,7 +138,6 @@ struct InputFunctionCoverageData {
 struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
   bool UseMultipleReaders;
   StringMap<unsigned> Files;
-  std::vector<std::string> Filenames;
   std::vector<InputFunctionCoverageData> InputFunctions;
   std::vector<OutputFunctionCoverageData> OutputFunctions;
 
@@ -233,13 +235,10 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
 
   void readCoverageRegions(const std::string &Coverage,
                            OutputFunctionCoverageData &Data) {
-    // We will re-use the StringRef in duplicate tests, clear it to avoid
-    // clobber previous ones.
-    Filenames.clear();
-    Filenames.resize(Files.size() + 1);
+    Data.FilenamesStorage.resize(Files.size() + 1);
     for (const auto &E : Files)
-      Filenames[E.getValue()] = E.getKey().str();
-    ArrayRef<std::string> FilenameRefs = llvm::ArrayRef(Filenames);
+      Data.FilenamesStorage[E.getValue()] = E.getKey().str();
+    ArrayRef<std::string> FilenameRefs = llvm::ArrayRef(Data.FilenamesStorage);
     RawCoverageMappingReader Reader(Coverage, FilenameRefs, Data.Filenames,
                                     Data.Expressions, Data.Regions);
     EXPECT_THAT_ERROR(Reader.read(), Succeeded());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PGO Profile Guided Optimizations
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants